/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package evotingclient.model;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.InetSocketAddress;
import java.nio.charset.Charset;
import java.security.InvalidAlgorithmParameterException;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.ManagerFactoryParameters;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactorySpi;
import javax.net.ssl.X509TrustManager;
import org.apache.mina.core.future.ConnectFuture;
import org.apache.mina.core.service.IoConnector;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.codec.textline.TextLineCodecFactory;
import org.apache.mina.filter.ssl.SslFilter;
import org.apache.mina.transport.socket.nio.NioSocketConnector;

/**
 *
 * @author Pawel
 */

class TrustManagerFactory2 extends TrustManagerFactorySpi {

    static final X509TrustManager X509 = new X509TrustManager() {

        public void checkClientTrusted(X509Certificate[] x509Certificates,
                String s) throws CertificateException {
        }

        @Override
        public void checkServerTrusted(X509Certificate[] x509Certificates,
                String s) throws CertificateException {
        }

        @Override
        public X509Certificate[] getAcceptedIssuers() {
            return new X509Certificate[0];
        }
    };
    static final TrustManager[] X509_MANAGERS = new TrustManager[]{X509};

    public TrustManagerFactory2() {
    }

    @Override
    protected TrustManager[] engineGetTrustManagers() {
        return X509_MANAGERS;
    }

    @Override
    protected void engineInit(KeyStore keystore) throws KeyStoreException {
        // noop
    }

    @Override
    protected void engineInit(ManagerFactoryParameters managerFactoryParameters)
            throws InvalidAlgorithmParameterException {
        // noop
    }
}

public class PKWClientMina {
    private static final int REMOTE_PORT = 9999;
    Model model;
    PKWClientHandler mHandler;

    public PKWClientMina(Model model) {
        this.model = model;
        mHandler = new PKWClientHandler(model);
    }
    
    
    
    public void register(String nick, String password) throws NoSuchAlgorithmException, KeyStoreException, FileNotFoundException, IOException, CertificateException, UnrecoverableKeyException, KeyManagementException{
         IoConnector connector = new NioSocketConnector();
        connector.getSessionConfig().setReadBufferSize(8192);
        
        // SSL stuff
            File pKeyFile = new File(model.getPath(CertificateManager.keystore));
            KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("SunX509");
            KeyStore keyStore = KeyStore.getInstance("JKS");

            InputStream keyInput = new FileInputStream(pKeyFile);
            keyStore.load(keyInput, password.toCharArray());
            keyInput.close();
            keyManagerFactory.init(keyStore, password.toCharArray());

            SSLContext context = SSLContext.getInstance("TLS");

            context.init(keyManagerFactory.getKeyManagers(), TrustManagerFactory2.X509_MANAGERS, null);
        // end SSL stuff
            
        SslFilter sslFilter = new SslFilter(context);
        sslFilter.setUseClientMode(true);
        connector.getFilterChain().addFirst("sslFilter", sslFilter);
        connector.getFilterChain().addLast("codec", new ProtocolCodecFilter(new TextLineCodecFactory(Charset.forName("UTF-8"))));
        connector.setHandler(mHandler);
        ConnectFuture future = connector.connect(new InetSocketAddress("localhost", REMOTE_PORT));
        future.awaitUninterruptibly();
        if(!future.isConnected()) {
            return;
        }
        IoSession session = future.getSession();
        //session.getConfig().setUseReadOperation(true);
        session.getCloseFuture().awaitUninterruptibly();
        connector.dispose();
    }
    
    
    
    
    public static void main(String[] argv) throws Exception {
       
        
        
    }

    
}
